<template>
  <v-snackbar v-model="visible" :color="messageColor" :timeout="timeout" :location="location" :multi-line="multiLine"
    :vertical="vertical" class="base-message" rounded="xl" elevation="9" transition="slide-y-transition">
    <div class="d-flex align-center message-content">
      <v-icon v-if="messageIcon" :icon="messageIcon" class="mr-3 message-icon" size="20" />
      <span class="message-text">{{ message }}</span>
    </div>

    <template v-slot:actions>
      <v-btn variant="text" size="small" @click="close" class="text-white close-btn">
        Close
      </v-btn>
    </template>
  </v-snackbar>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';

export interface MessageOptions {
  message: string;
  type?: 'success' | 'error' | 'warning' | 'info';
  timeout?: number;
  location?: string;
  multiLine?: boolean;
  vertical?: boolean;
}

// Props
const props = withDefaults(defineProps<{
  modelValue: boolean;
  options: MessageOptions;
}>(), {
  modelValue: false,
  options: () => ({
    message: '',
    type: 'info',
    timeout: 40000,
    location: 'top',
    multiLine: false,
    vertical: false
  })
});

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean];
  'close': [];
}>();

// 响应式数据
const visible = ref(props.modelValue);

// 计算属性
const message = computed(() => props.options.message);
const timeout = computed(() => props.options.timeout || 4000);
const location = computed(() => props.options.location || 'top');
const multiLine = computed(() => props.options.multiLine || false);
const vertical = computed(() => props.options.vertical || false);

// 消息颜色映射
const messageColor = computed(() => {
  const colorMap = {
    success: 'success',
    error: 'error',
    warning: 'warning',
    info: 'info'
  };
  return colorMap[props.options.type || 'info'];
});

// 消息图标映射
const messageIcon = computed(() => {
  const iconMap = {
    success: 'mdi-check-circle',
    error: 'mdi-alert-circle',
    warning: 'mdi-alert',
    info: 'mdi-information'
  };
  return iconMap[props.options.type || 'info'];
});

// 监听 modelValue 变化
watch(() => props.modelValue, (newVal) => {
  visible.value = newVal;
});

// 监听 visible 变化
watch(visible, (newVal) => {
  emit('update:modelValue', newVal);
  if (!newVal) {
    emit('close');
  }
});

// 关闭方法
const close = () => {
  visible.value = false;
};

// 暴露方法
defineExpose({
  close
});
</script>

<style scoped>
.base-message {
  z-index: 9999;
}

.base-message :deep(.v-snackbar__wrapper) {
  border-radius: 12px !important;
  box-shadow: 0 12px 20px -10px rgba(0, 0, 0, 0.28),
    0 4px 20px 0px rgba(0, 0, 0, 0.12),
    0 7px 8px -5px rgba(0, 0, 0, 0.2) !important;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
}

/* 入场动画 */
.base-message :deep(.v-snackbar--active) {
  animation: messageSlideIn 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

/* 出场动画 */
.base-message :deep(.v-snackbar:not(.v-snackbar--active)) {
  animation: messageSlideOut 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

@keyframes messageSlideIn {
  0% {
    transform: translateY(-100%) scale(0.8);
    opacity: 0;
  }

  60% {
    transform: translateY(10%) scale(1.05);
    opacity: 0.8;
  }

  100% {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

@keyframes messageSlideOut {
  0% {
    transform: translateY(0) scale(1);
    opacity: 1;
  }

  100% {
    transform: translateY(-100%) scale(0.8);
    opacity: 0;
  }
}

.message-content {
  /* 内容随弹框一起显示，无需独立动画 */
}

.message-icon {
  /* 图标随弹框一起显示，无需独立动画 */
}

.message-text {
  word-break: break-word;
  line-height: 1.4;
  font-weight: 500;
}

.close-btn {
  transition: all 0.2s ease !important;
}

/* 确保不同类型的消息有合适的对比度 */
.base-message :deep(.v-snackbar--variant-filled) {
  color: white !important;
}

.base-message :deep(.v-btn) {
  color: rgba(255, 255, 255, 0.9) !important;
}

.base-message :deep(.v-btn:hover) {
  background-color: rgba(255, 255, 255, 0.1) !important;
  transform: scale(1.05);
}

/* 响应式设计 - 在小屏幕上保持一致的体验 */
@media (max-width: 600px) {
  @keyframes messageSlideIn {
    0% {
      transform: translateY(-50%) scale(0.9);
      opacity: 0;
    }

    100% {
      transform: translateY(0) scale(1);
      opacity: 1;
    }
  }
}
</style>